package edu.amm.fanal.api;

import edu.amm.api.Bounds;

/**
 * Координатная системы в пространстве функций, заданных на отрезке.
 * 
 * @author Иванов Илья
 * @since 2013-05-12
 *
 */
public abstract class Coordinates extends Bounds {
	
	protected Coordinates(Bounds bounds) {
		super(bounds);
	}
	
	/**
	 * @param count Количество координат.
	 * @return Набор из <code>count<code> первых координат.
	 */
	public Function[] getCoordinates(int count) {
		if (count < 1)
			throw new RuntimeException("Количество координат должно быть положительным");
		
		return coordinates(count);
	}
	
	/**
	 * @return Название координатрой системы.
	 */
	public abstract String getName();
	
	/**
	 * @param count Количество координат.
	 * @return Набор из <code>count<code> первых координат.
	 */
	protected abstract Function[] coordinates(int count);
	
	/**
	 * Тип координатной системы.
	 * 
	 * @author Иванов Илья
	 * @since 2013-05-16
	 *
	 */
	public enum CoordinatesType {
		
		/**
		 * Синусы.
		 */
		SINE {
			
			protected Coordinates getInstance(Bounds bounds) {
				return new SineCoordinates(bounds);
			}
			
			public String toString() {
				return SineCoordinates.getCoordinatesName();
			}
		},
		
		/**
		 * Интегралы от -1 до x от многочленов Лежандра.
		 */
		INTEGRAL_LEGENDRE {
			
			protected Coordinates getInstance(Bounds bounds) {
				return new IntegralLegendreCoordinates();
			}
			
			public String toString() {
				return IntegralLegendreCoordinates.getCoordinatesName();
			}
		};
		
		/**
		 * @param bounds Границы отрезка, на котором будут заданы координатные функции.
		 * @return Координатная система.
		 */
		public Coordinates instantiate(Bounds bounds) {
			if (bounds == null)
				throw new RuntimeException("Не заданы границы отрезка для функций координатной системы");
			
			return getInstance(bounds);
		}
		
		protected abstract Coordinates getInstance(Bounds bounds);
	}
}